﻿using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;

namespace Kay.BaseLibrary.Helpers
{
    /// <summary>
    /// 转换帮助器
    /// </summary>
    public static class ConvertHelper
    {
        /// <summary>
        /// DataTable 转换 List
        /// </summary>
        /// <typeparam name="T">List 类型</typeparam>
        /// <param name="value">需要转换的 DataTable</param>
        /// <returns>转换后的 List 列表</returns>
        public static IList<T> ToList<T>(DataTable value) where T : new()
        {
            GC.Collect();
            var toList = new List<T>();
            var type = typeof(T);
            var propertyInfos = type.GetProperties();
            foreach (DataRow row in value.Rows)
            {
                var t = new T();
                foreach (var propertyInfo in propertyInfos)
                {
                    var propertyInfoName = propertyInfo.Name;
                    if (!value.Columns.Contains(propertyInfoName))
                        continue;

                    if (!propertyInfo.CanWrite)
                        continue;

                    var o = row[propertyInfoName];
                    if (o != DBNull.Value)
                        propertyInfo.SetValue(t, o, null);
                }

                toList.Add(t);
            }
            GC.Collect();
            return toList;
        }

        /// <summary>
        /// 使用 Buffer 将字节数据转换为字符串
        /// </summary>
        /// <param name="bytes">需要转换的字节数组</param>
        /// <returns>转换后的字符串</returns>
        public static string ToStringByBuffer(byte[] bytes)
        {
            if (bytes == null || bytes.Length == 0)
                return string.Empty;
            var chars = new char[bytes.Length / sizeof(char)];
            Buffer.BlockCopy(bytes, 0, chars, 0, bytes.Length);
            return new string(chars);
        }

        /// <summary>
        /// 将字符串转换为 Byte 数组
        /// </summary>
        /// <param name="value">需要转换的字符串</param>
        /// <returns>转换后的字节数组</returns>
        public static byte[] ToBytesByBuffer(string value)
        {
            if (string.IsNullOrEmpty(value))
            {
                return null;
            }
            var bytes = new byte[value.Length * sizeof(char)];
            Buffer.BlockCopy(value.ToCharArray(), 0, bytes, 0, bytes.Length);
            return bytes;
        }

        /// <summary>
        /// 将 Model 列表对象转换为 <see cref="DataTable"/>
        /// </summary>
        /// <typeparam name="T">数据模型类</typeparam>
        /// <param name="listModel">模型数据</param>
        /// <returns><see cref="DataTable"/> 数据</returns>
        public static DataTable ToDataTable<T>(IEnumerable<T> listModel)
        {
            GC.Collect();
            var properties = TypeDescriptor.GetProperties(typeof(T));
            var dt = new DataTable();
            for (var i = 0; i < properties.Count; i++)
            {
                var property = properties[i];
                var type = property.PropertyType;
                if (type.IsGenericType && type.GetGenericTypeDefinition() == typeof(Nullable<>))
                {
                    type = type.GetGenericArguments()[0];
                }
                dt.Columns.Add(property.Name, type);
            }
            var values = new object[properties.Count];
            foreach (var item in listModel)
            {
                for (var i = 0; i < values.Length; i++)
                {
                    values[i] = properties[i].GetValue(item);
                }
                dt.Rows.Add(values);
            }
            GC.Collect();
            return dt;
        }
    }
}